package cn.afterturn.easypoi.word.parse;

import cn.afterturn.easypoi.entity.ImageEntity;
import cn.afterturn.easypoi.util.PoiElUtil;
import cn.afterturn.easypoi.word.entity.bookmark.ExportExecel.Constant;
import cn.afterturn.easypoi.word.entity.bookmark.ExportExecel.ExcelInOutParent;
import cn.afterturn.easypoi.word.entity.bookmark.ExportExecel.NormalParagraph;
import cn.afterturn.easypoi.word.entity.bookmark.ExportExecel.TablePara;
//import sun.plugin2.util.PojoUtil;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

import static cn.afterturn.easypoi.util.PoiElUtil.END_STR;
import static cn.afterturn.easypoi.util.PoiElUtil.START_STR;

public class BookmarkHandle {
    private static SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd");
    public static boolean isFromNetWork=false;
    public Map<String, Object> handleNormalParagraph(List<NormalParagraph> normalParagraphs) {
        Map<String, Object> map = new HashMap<String, Object>();
        normalParagraphs.forEach(normalParagraph -> {
           ExcelRowParentToMap(normalParagraph,map);
        });
        return map;
    }

    private ImageEntity setPictureUrl(NormalParagraph normalParagraph) {
        ImageEntity image = new ImageEntity();
        image.setHeight(Integer.parseInt(normalParagraph.getHigh()));
        image.setWidth(Integer.parseInt(normalParagraph.getWidth()));
        image.setUrl(normalParagraph.getImagPath());
        image.setType(ImageEntity.URL);
        return image;

    }

    /*
     * 新创建一个ImageEntity，对它的值，采用Byte[]方式填入
     * */
    private ImageEntity setPictureType(NormalParagraph normalParagraph) throws Exception {
        ImageEntity image = new ImageEntity();
        image.setHeight(Integer.parseInt(normalParagraph.getHigh()));
        image.setWidth(Integer.parseInt(normalParagraph.getWidth()));
        image.setData(getBytes(normalParagraph.getImagPath()));
        //image.setUrl(normalParagraph.getImagPath());
        //File file=new File("E:\\file.doc");
        String fileName = normalParagraph.getImagPath();
        String fileType = fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length());
        image.setType(fileType);
        System.out.println("fileType:" + fileType);
        //image.setType(ImageEntity.URL);
        return image;
    }

    private byte[] getBytes(String filePath) throws Exception {
        byte[] buffer = null;
        try {
            File file = new File(filePath);
            FileInputStream fis = new FileInputStream(file);
            ByteArrayOutputStream bos = new ByteArrayOutputStream(1000);
            byte[] b = new byte[1000];
            int n;
            while ((n = fis.read(b)) != -1) {
                bos.write(b, 0, n);
            }
            fis.close();
            bos.close();
            buffer = bos.toByteArray();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return buffer;
    }

    public Map<String, Object> handleTableParagraphExt(List<TablePara> tableParas) {
        Map<String, Object> map = new HashMap<String, Object>();
        Iterator<TablePara> iterator = tableParas.iterator();
        //把fe的部分，删除
        while (iterator.hasNext()) {
            TablePara tablePara = iterator.next();
            if (tablePara.getBookMarkName().contains("{{" + PoiElUtil.FOREACH + "}}")) {
                iterator.remove();
            }
        }
        //把不循环的取出来
        List<TablePara> rowNoLoopList=new ArrayList<>();
        for (TablePara tablePara : tableParas) {
            if (!tablePara.getRowFirstColumnText().contains("{{fe:}}")){
                ExcelRowParentToMap(tablePara,map);
                rowNoLoopList.add(tablePara);
            }
        }
        tableParas.removeAll(rowNoLoopList);
        /*tableParas.forEach(
                tablePara -> {
                    String currentText = tablePara.getBookMarkName();
                    currentText = currentText.substring(currentText.indexOf(START_STR) + 2, currentText.indexOf(END_STR));
                    if (!tablePara.getRowFirstColumnText().contains("{{fe:}}")) {
                        ExcelRowParentToMap(tablePara,map);
                       }
                });
        //把不循环的删除
        iterator = tableParas.iterator();
        while (iterator.hasNext()) {
            TablePara tablePara = iterator.next();
            String currentText = tablePara.getBookMarkName();
            currentText = currentText.substring(currentText.indexOf(START_STR) + 2, currentText.indexOf(END_STR));
            if (map.containsKey(currentText)) {
                iterator.remove();
            }
        }*/
        //把循环的行所对应的bookmark取出来，以表+行作为key
        Map<String, List<TablePara>> mapTablePara = tableParas.stream()
                .collect(Collectors.groupingBy(e -> fetchGroupKey(e)));
        mapTablePara.forEach((k, v) -> {
            String key = k;
            List<Map<String, Object>> mapList = new ArrayList<>();
            //https://blog.csdn.net/wysnxzm/article/details/78930110
            //http://ddrv.cn/a/280896
            //按照getBookMarkValuesequence，进行升序排列
            //要寻求一个对分组进行排序，然后对分组及组内的内容同时进行排序的方法
            TreeMap<String, List<TablePara>> matchsListMap = v.stream()
                    .collect(Collectors.groupingBy(TablePara::getBookMarkValuesequence, TreeMap::new, Collectors.toList()));


            matchsListMap.forEach((a, z) -> {
                Map<String, Object> m1 = new HashMap<>();
                z.forEach(s -> {
                    ExcelRowParentToMap(s,m1);
                    });
                mapList.add(m1);
            });

            map.put(key, mapList);
        });
        return map;
            /*//对V集合进行排序,从小到大
            v.stream().sorted(Comparator.comparing(TablePara::getBookMarkValuesequence));
            v.forEach(tablePara -> {
                String currentText=tablePara.getBookMarkName();
                currentText=currentText.substring(currentText.indexOf(START_STR) + 2, currentText.indexOf(END_STR));

                if (!tablePara.getBookMarkName().contains("{{fe:}}")) {//先把这个过滤掉
                   Map<String, Object> rowMap = new HashMap<>();//一行对于一个Map
                    mapList.add(rowMap);

                    if (tablePara.getBookmarkType().contains("普通书签")) {
                        rowMap.put(currentText, tablePara.getBookmarkValue());
                    }

                    if (tablePara.getBookmarkType().contains("计算值")) {
                        if (tablePara.getBookmarkType().toLowerCase().contains("now()")) {
                            rowMap.put(currentText, format.format(new Date()));
                        } else {
                            rowMap.put(currentText, "");
                        }
                    }
                    if (tablePara.getBookmarkType().contains("图片")) {
                        ImageEntity image = new ImageEntity();
                        image.setHeight(Integer.parseInt(tablePara.getHigh()));
                        image.setWidth(Integer.parseInt(tablePara.getWidth()));
                        image.setUrl(tablePara.getImagPath());
                        image.setType(ImageEntity.URL);
                        rowMap.put(currentText, image);
                    }

                }
            });
        });*/

    }

    //Java8 stream 中利用 groupingBy 进行多字段分组求和
    //https://www.cnblogs.com/winner-0715/p/10246037.html
    private static String fetchGroupKey(TablePara tablePara) {
        return tablePara.getTableText().hashCode() + "#" + tablePara.getRowno();
    }

    private static void ExcelRowParentToMap(ExcelInOutParent excelInOutParent,Map<String, Object> map) {

        String currentText = excelInOutParent.getBookMarkName().trim();
        currentText = currentText.substring(currentText.indexOf(START_STR) + 2, currentText.indexOf(END_STR));
        if (excelInOutParent.getBookmarkType().contains(Constant.NormalbookMark)) {

            map.put(currentText, excelInOutParent.getBookmarkValue());
        }
        if (excelInOutParent.getBookmarkType().contains(Constant.ComputedbookMark)) {

            if (excelInOutParent.getBookMarkName().toLowerCase().contains(Constant.NOW)) {
                map.put(currentText, format.format(new Date()));
            }
                //对图片的新处理方式
            if (excelInOutParent.getBookMarkName().contains(Constant.PICTURE)) {
                    try {
                        //这个方法姜晓东给我的新方法进行替换
                        if(!isFromNetWork) {
                            ImageEntity image = ImageParse.parseImage(excelInOutParent.getBookMarkName().trim());
                            map.put(currentText.trim(), image);
                        }
                        if(isFromNetWork){
                            ImageEntity image = ImageParse.parseImage(excelInOutParent.getBookMarkName().trim(),excelInOutParent.getBookmarkValue());
                            map.put(currentText.trim(), image);
                        }
                        //map.put(currentText.trim(), image);
                    } catch (Exception ex) {

                    }

                }
            }
        }




        /*
        * 对2个Map进行合并，排序，打印
        * */
     public Map<String,Object> mapcombined(Map<String,Object> mapNormal,Map<String,Object> mapTable){
         Map<String,Object>  mapcombined=new HashMap<>();
         //如果table中的bookmark与正常的bookmark的key一样，那么前面的就被覆盖了。在Map中的key唯一
         mapNormal.forEach((k,v)->{
             mapcombined.put(k,v);
         });
         mapTable.forEach((k,v)->{
             mapcombined.put(k,v);
         });
         mapcombined.entrySet().stream().sorted(Comparator.comparing(e -> e.getKey()));
         System.out.println("打印Map的值----------------------------------------------------------------");
         mapcombined.forEach((k,v)->{
             System.out.println(k.toString());
             if(v instanceof  List){
                 ((List) v).forEach(t->{
                     System.out.println(t.toString());
                 });
             }
             else{
                 if(v instanceof String)
                 {
                     System.out.println(v);
                 }
             }
         });
         return mapcombined;
     }

}
